package util

import (
	_ "crypto/cipher"
	"encoding/base64"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"github.com/duke-git/lancet/v2/strutil"
	"github.com/sigurn/crc16"
	"github.com/tjfoc/gmsm/sm4"
	"hash/crc32"
	"strconv"
	"strings"
)

// StringToBytes 字符串转化为 byte 数组
func StringToBytes(s string) []byte {
	return []byte(s)
}

// BytesToString byte 数组转化为字符串
func BytesToString(b []byte) string {
	return strutil.Trim(strutil.BytesToString(b))
}

// HexToBytes hex转化为 byte 数组
func HexToBytes(s string) []byte {
	decodeString, err := hex.DecodeString(s)
	if err != nil {
		fmt.Println(err)
	}
	return decodeString
}

// BytesToHex byte 数组转化为 hex
func BytesToHex(b []byte) string {
	return hex.EncodeToString(b)
}

// Uint32ToBytesBig uint32 大端转化为 byte 数组
func Uint32ToBytesBig(num uint32) []byte {
	bytes := make([]byte, 4)
	binary.BigEndian.PutUint32(bytes, num)
	return bytes
}

// BytesToUint32Big  byte 大端数组转化为 uint32
func BytesToUint32Big(b []byte) uint32 {
	return binary.BigEndian.Uint32(b)
}

// Uint16ToBytesBig uint16 大端转化为 byte 数组
func Uint16ToBytesBig(num uint16) []byte {
	bytes := make([]byte, 2)
	binary.BigEndian.PutUint16(bytes, num)
	return bytes
}

// BytesToUint16Big  byte 大端数组转化为 uint16
func BytesToUint16Big(b []byte) uint16 {
	return binary.BigEndian.Uint16(b)
}

// Uint32ToBytesLittle uint32 小端转化为 byte 数组
func Uint32ToBytesLittle(num uint32) []byte {
	bytes := make([]byte, 4)
	binary.LittleEndian.PutUint32(bytes, num)
	return bytes
}

// BytesToUint32Little  byte 小端数组转化为 uint32
func BytesToUint32Little(b []byte) uint32 {
	return binary.LittleEndian.Uint32(b)
}

// Uint64ToBytesBig uint64 大端转化为 byte 数组
func Uint64ToBytesBig(num uint64) []byte {
	bytes := make([]byte, 8)
	binary.BigEndian.PutUint64(bytes, num)
	return bytes
}

// BytesToUint64Big  byte 大端数组转化为 uint64
func BytesToUint64Big(b []byte) uint64 {
	return binary.BigEndian.Uint64(b)
}

// Uint64ToBytesLittle uint64 小端转化为 byte 数组
func Uint64ToBytesLittle(num uint64) []byte {
	bytes := make([]byte, 8)
	binary.LittleEndian.PutUint64(bytes, num)
	return bytes
}

// BytesToUint64Little  byte 小端数组转化为 uint64
func BytesToUint64Little(b []byte) uint64 {
	return binary.LittleEndian.Uint64(b)
}

// BytesAppend  byte 数组拼接 通过append一个空数组里面添加元素
func BytesAppend(arrays ...[]byte) []byte {
	var c []byte
	for _, a := range arrays {
		c = append(c, a...)
	}
	return c
}

// Sm4Encrypt  sm4Ecb模式pksc7填充加密
func Sm4Encrypt(key []byte, b []byte) []byte {
	encrypt, err := sm4.Sm4Ecb(key, b, true)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	return encrypt
}

// Sm4Decrypt  sm4Ecb模式pksc7填充解密密
func Sm4Decrypt(key []byte, b []byte) []byte {
	encrypt, err := sm4.Sm4Ecb(key, b, false)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	return encrypt
}

func DecodeHexOrBase64(content string) ([]byte, error) {
	dat := []byte(content)
	isHex := true
	for _, v := range dat {
		if v >= 48 && v <= 57 || v >= 65 && v <= 70 || v >= 97 && v <= 102 {
			// isHex = true
		} else {
			isHex = false
			break
		}
	}
	if isHex {
		d, err := hex.DecodeString(content)
		if len(d) == 0 || err != nil {
			return base64.StdEncoding.DecodeString(content)
		}
		return d, err
	} else {
		return base64.StdEncoding.DecodeString(content)
	}
}

// ResponseBizDecryptBytes 解密数据
func ResponseBizDecryptBytes(encryptType uint32, encryptKey string, dataBytes []byte) []byte {

	// 没有加密
	if encryptType == 0 || len(encryptKey) != 32 {
		return dataBytes
	} else if encryptType == 3 && len(encryptKey) == 32 {
		Sm4Decrypt(HexToBytes(encryptKey), dataBytes)
	}
	return dataBytes
}

// StandardBefore 获取锁的字节码数据
func StandardBefore(bytes []byte, length int) []byte {

	if len(bytes) < length {
		zeroByte := make([]byte, 1)
		zeroByte[0] = 0
		return StandardBefore(BytesAppend(zeroByte, bytes), length)
	}
	return bytes
}

// StandardAfter 获取锁的字节码数据
func StandardAfter(bytes []byte, length int) []byte {

	if len(bytes) < length {
		zeroByte := make([]byte, 1)
		zeroByte[0] = 0
		return StandardBefore(BytesAppend(bytes, zeroByte), length)
	}
	return bytes
}

// Crc16 校验
func Crc16(bytes []byte) []byte {
	//使用ECMA多项式创建表
	table := crc16.MakeTable(crc16.CRC16_KERMIT)

	//计算CRC64校验和
	crc := crc16.Checksum(bytes, table)

	//校验位
	return Uint16ToBytesBig(crc)
}

// ParseFirmwareVersion 解析锁版本, 字节数组
func ParseFirmwareVersion(firmwareVersionBytes []byte) string {

	firmwareVersion := ""
	for i := 0; i < 4; i++ {
		integer := BytesToUint32Big(StandardBefore(firmwareVersionBytes[i:i+1], 4))
		if i == 0 {
			firmwareVersion = firmwareVersion + strconv.Itoa(int(integer))
		} else {
			s := strconv.Itoa(int(integer))
			if len(s) == 1 {
				s = "0" + s
			}
			firmwareVersion = firmwareVersion + "." + s
		}
	}
	return firmwareVersion
}

// CheckMd5Sign 校验签名，不通过抛出异常
func CheckMd5Sign(beforeMd5SignBytes []byte, receiveMd5SignBytes []byte, signKeyBytes []byte) bool {
	boolFlag := false
	md5SignBytes := Md5(BytesAppend(beforeMd5SignBytes, signKeyBytes))
	if strings.EqualFold(BytesToHex(receiveMd5SignBytes), BytesToHex(md5SignBytes)) {
		boolFlag = true
	}
	return boolFlag
}

func HashCode(s string) uint32 {
	v := crc32.ChecksumIEEE([]byte(s))
	return v
}

///**
// * 获取锁的字节码数据
// */
//public static byte[] getStandardBefore(byte[] bytes, Integer length) {
//
//if (bytes.length < length) {
//byte[] zeroByte = {0};
//return NBLockV2Utils.getStandardBefore(NBLockV2Utils.concatAll(zeroByte, bytes), length);
//}
//return bytes;
//}

//func main() {

//// 字符串
//s := "你好"
//bytes := StringToBytes(s)
//fmt.Println(bytes)
//fmt.Println(BytesToString(bytes))
//newUUID, err := uuid.NewUUID()
//if err != nil {
//	fmt.Println(err)
//}
//
//// hex 字符串
//all := strings.ReplaceAll(newUUID.String(), "-", "")
//fmt.Println(all)
//toBytes := HexToBytes(all)
//fmt.Println(toBytes)
//toString := BytesToHex(toBytes)
//fmt.Println(toString)
//
//bytes = []byte{0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12}
//fmt.Printf(
//	"LittleEndian: %d\n",
//	BytesToUint64Little(bytes),
//)
//fmt.Printf(
//	"BigEndian: %d\n",
//	BytesToUint64Big(bytes),
//)
//num := uint64(8671175386481439762)
//fmt.Println("int32 to bytes:", Uint64ToBytesBig(num))
//
//
// 使用append函数拼接切片
//slice1 := []byte{1, 2, 3}
//slice2 := []byte{4, 5, 6}
//slice3 := []byte{7, 8, 9}
//bytesAppend := BytesAppend(slice1, slice2, slice3)
//fmt.Println(bytesAppend)

// SM4 ecb pkcs7 加解密
//key := HexToBytes("b262e623a00a11efaff800fffc488f06")
//fmt.Printf("key = %v\n", key)
//data := StringToBytes("1234567890")
//ecbMsg := Sm4Encrypt(key, data)
//fmt.Println("加密数据 = ", BytesToHex(ecbMsg))
//ecbDec := Sm4Decrypt(key, ecbMsg) //sm4Ecb模式pksc7填充解密
//fmt.Println("加密数据 ecbDec = ", BytesToString(ecbDec))

//priv, err := sm2.GenerateKey(rand.Reader) // 生成密钥对
//if err != nil {
//	log.Fatal(err)
//}
//msg := []byte("Tongji Fintech Research Institute")
//pub := &priv.PublicKey
//ciphertxt, err := pub.EncryptAsn1(msg, rand.Reader) //sm2加密
//if err != nil {
//	log.Fatal(err)
//}
//fmt.Printf("加密结果:%x\n", ciphertxt)
//plaintxt, err := priv.DecryptAsn1(ciphertxt) //sm2解密
//if err != nil {
//	log.Fatal(err)
//}
//if !bytes.Equal(msg, plaintxt) {
//	log.Fatal("原文不匹配")
//}
//
//fmt.Println("解密结果:", BytesToString(plaintxt))
//
//sign, err := priv.Sign(rand.Reader, msg, nil) //sm2签名
//if err != nil {
//	log.Fatal(err)
//}
//isok := pub.Verify(msg, sign) //sm2验签
//fmt.Printf("Verified: %v\n", isok)
//
//randInt := random.RandInt(0, 100)
//
//fmt.Println(randInt)

//bufio.Reader{}.
//}
